/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.shape;

import br.ufmg.dees.insane.util.IMatrix;
import br.ufmg.dees.insane.util.IVector;


/**
 *  A class representing shape referring to the
 *  quadrilateral plate-bending element of nine node 
 *  developed by Hughes and Cohen, called Heterosis.
*
*@author Samir
*@version 1.0
*@since 13/07/2006
*/

public class Q9H extends ShapeC0 {
	
	private static final long serialVersionUID = 1L;

	/** Returns the IVector containing the values of shape function evalueted in provided points.
	*@param g The vector containing the coordinates which the shape function will be evalueted.
	*@param cN The matrix containing nodal coordinates in cartesian system.
	*@return The IVector containing the values of shape function evalueted in provided points.
	*/
	public IVector getShapeFunction(double[] g, IMatrix cN) 
	{
		double a = g[0];
		double b = g[1];
		
		IVector n = new IVector(17);

	// shape function Q9
		double nL0 = ((0.25)*(1-a)*(1-b)*(a*b));
		double nL1 = ((-0.5)*(1-(a*a))*(1-b)*(b));
		double nL2 = ((-0.25)*(1+a)*(1-b)*(a*b));
		double nL3 = ((0.5)*(1+a)*(1-(b*b))*(a));
		double nL4 = ((0.25)*(1+a)*(1+b)*(a*b));
		double nL5 = ((0.5)*(1-(a*a))*(1+b)*(b));
		double nL6 = ((-0.25)*(1-a)*(1+b)*(a*b));
		double nL7 = ((-0.5)*(1-a)*(1-(b*b))*(a));
		double nL8 = ((1-(a*a))*(1-(b*b)));

	// shape function Q8
		double nS0 = ((-0.25)*(1-a)*(1-b)*(1+a+b));
		double nS1 = ((0.5)*(1-(a*a))*(1-b)); 
		double nS2 = ((0.25)*(1+a)*(1-b)*(a-b-1));
		double nS3 = ((0.5)*(1+a)*(1-(b*b)));
		double nS4 = ((-0.25)*(1+a)*(1+b)*(1-a-b));
		double nS5 = ((0.5)*(1-(a*a))*(1+b));
		double nS6 = ((-0.25)*(1-a)*(1+b)*(1+a-b));
		double nS7 = ((0.5)*(1-a)*(1-(b*b)));

		n.setElement(0,nL0);
		n.setElement(1,nL1);
		n.setElement(2,nL2);
		n.setElement(3,nL3);
		n.setElement(4,nL4);
		n.setElement(5,nL5);
		n.setElement(6,nL6);
		n.setElement(7,nL7);
		n.setElement(8,nL8);
		
		n.setElement(9,nS0);
		n.setElement(10,nS1);
		n.setElement(11,nS2);
		n.setElement(12,nS3);
		n.setElement(13,nS4);
		n.setElement(14,nS5);
		n.setElement(15,nS6);
		n.setElement(16,nS7);

		return (n);
	}
	
	/** Returns the IMatrix containing the values of shape function derived in xi and eta evalueted in provided points.
	*@param g The vector containing the coordinates which the shape function will be evalueted.
	*@param cN The matrix containing nodal coordinates in cartesian system.
	*@return The IMatrix containing the values of shape function derived in xi and eta evalueted in provided points.
	*/
	public IMatrix getDerivedShapeFunction(double[] g, IMatrix cN) 
	{
		double a = g[0]; //g[0] refere-se a coordenada xi
		double b = g[1]; //g[1] refere-se a coordenada eta
		
		IMatrix dl = new IMatrix(2,17);
		
	//derivadas em relacao a xi (a = xi e b = eta)
		double dlL0 = (0.25)*(1-2*a)*(1-b)*b;
		double dlL1 = (1-b)*a*b;
		double dlL2 = (-1)*(0.25)*(1+2*a)*(1-b)*b;
		double dlL3 = (0.5)*(1+2*a)*(1-(b*b));
		double dlL4 = (0.25)*(1+2*a)*(1+b)*b;
		double dlL5 = (-1)*(1+b)*a*b;
		double dlL6 = (-1)*(0.25)*(1-2*a)*(1+b)*b;
		double dlL7 = (-1)*(0.5)*(1-2*a)*(1-(b*b));
		double dlL8 = (-1)*2*(1-(b*b))*a;

		double dlS0 = (0.25)*(1-b)*((2*a)+b);
		double dlS1 = (-1)*(1-b)*(a);
		double dlS2 = (0.25)*(1-b)*((2*a)-b);
		double dlS3 = (0.5)*(1-(b*b));
		double dlS4 = (0.25)*(1+b)*((2*a)+b);
		double dlS5 = (-1)*(1+b)*(a);
		double dlS6 = (0.25)*(1+b)*((2*a)-b);
		double dlS7 = (-0.5)*(1-(b*b));

		//derivadas em relacao a eta (a = xi e b = eta)
		double dlL9 = (0.25)*(1-a)*(1-2*b)*a;
		double dlL10 = (-1)*(0.5)*(1-(a*a))*(1-2*b);
		double dlL11 = (-1)*(0.25)*(1+a)*(1-2*b)*a;
		double dlL12 = (-1)*(1+a)*a*b;
		double dlL13 = (0.25)*(1+a)*(1+2*b)*a;
		double dlL14 = (0.5)*(1-(a*a))*(1+2*b);
		double dlL15 = (-1)*(0.25)*(1-a)*(1+2*b)*a;
		double dlL16 = (1-a)*a*b;
		double dlL17 = (-1)*2*(1-(a*a))*b;

		double dlS8 = (0.25)*(1-a)*(a+(2*b));
		double dlS9 = (-0.5)*(1-(a*a));
		double dlS10 = (-0.25)*(1+a)*(a-(2*b));
		double dlS11 = (-1)*(1+a)*(b);
		double dlS12 = (0.25)*(1+a)*(a+(2*b));
		double dlS13 = (0.5)*(1-(a*a));
		double dlS14 = (-0.25)*(1-a)*(a-(2*b));
		double dlS15 = (-1)*(1-a)*(b);
	//derivadas em relacao a xi na linha 0 da IMatrix
		dl.setElement(0,0,dlL0);
		dl.setElement(0,1,dlL1);
		dl.setElement(0,2,dlL2);
		dl.setElement(0,3,dlL3);
		dl.setElement(0,4,dlL4);
		dl.setElement(0,5,dlL5);
		dl.setElement(0,6,dlL6);
		dl.setElement(0,7,dlL7);
		dl.setElement(0,8,dlL8);

		dl.setElement(0,9,dlS0);
		dl.setElement(0,10,dlS1);
		dl.setElement(0,11,dlS2);
		dl.setElement(0,12,dlS3);
		dl.setElement(0,13,dlS4);
		dl.setElement(0,14,dlS5);
		dl.setElement(0,15,dlS6);
		dl.setElement(0,16,dlS7);
		//derivadas em relacao a eta na linha 1 da IMatrix
		dl.setElement(1,0,dlL9);
		dl.setElement(1,1,dlL10);
		dl.setElement(1,2,dlL11);
		dl.setElement(1,3,dlL12);
		dl.setElement(1,4,dlL13);
		dl.setElement(1,5,dlL14);
		dl.setElement(1,6,dlL15);
		dl.setElement(1,7,dlL16);
		dl.setElement(1,8,dlL17);
		
		dl.setElement(1,9,dlS8);
		dl.setElement(1,10,dlS9);
		dl.setElement(1,11,dlS10);
		dl.setElement(1,12,dlS11);
		dl.setElement(1,13,dlS12);
		dl.setElement(1,14,dlS13);
		dl.setElement(1,15,dlS14);
		dl.setElement(1,16,dlS15);

		return (dl);
	}
	
	/** Return the IMatrix containing nodal coordinates of this shape in natural system.
	*@return natCoords The IMatrix with nodal coordinates of this shape in natural system.
	*/
	public IMatrix getNaturalNodalCoords(){
		IMatrix natCoords = new IMatrix(2,9);
		
	//coordenadas naturais de xi
		natCoords.setElement(0,0,-1);
		natCoords.setElement(0,1,0);
		natCoords.setElement(0,2,1);
		natCoords.setElement(0,3,1);
		natCoords.setElement(0,4,1);
		natCoords.setElement(0,5,0);
		natCoords.setElement(0,6,-1);
		natCoords.setElement(0,7,-1);
		natCoords.setElement(0,8,0);
		
	//coodenadas naturais de eta
		natCoords.setElement(1,0,-1);
		natCoords.setElement(1,1,-1);
		natCoords.setElement(1,2,-1);
		natCoords.setElement(1,3,0);
		natCoords.setElement(1,4,1);
		natCoords.setElement(1,5,1);
		natCoords.setElement(1,6,1);
		natCoords.setElement(1,7,0);
		natCoords.setElement(1,8,0);
		
			return natCoords;
	}

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.shape.Shape2D#getType()
     */
    public String getType() {
        return "Q9H";
    }
	
}
